package labox.innovation.gameserver.model.actor.instance;

import java.util.List;

import labox.innovation.gameserver.ai.CtrlIntention;
import labox.innovation.gameserver.model.L2CharPosition;
import labox.innovation.gameserver.model.actor.L2Attackable;
import labox.innovation.gameserver.model.actor.L2Character;
import labox.innovation.gameserver.model.actor.L2Npc;
import labox.innovation.gameserver.model.actor.knownlist.MonsterKnownList;
import labox.innovation.gameserver.templates.chars.NpcTemplate;
import labox.innovation.gameserver.timer.Timer;
import labox.innovation.gameserver.util.MinionList;
import labox.innovation.util.Rnd;

/**
 * 通常型怪物对象
 * 
 * L2MonsterInstance :<BR>
 * <BR>
 * <li>L2MinionInstance</li> <li>L2RaidBossInstance</li> <li>L2GrandBossInstance</li>
 * 
 * @version $Revision: 1.20.4.6 $ $Date: 2005/04/06 16:13:39 $
 */
public class FuzeMonsterInstance extends L2Attackable {

	/**
	 * 此怪物管理的仆从列表
	 */
	protected final MinionList _minionList;

	/**
	 * 仆从重生定时器
	 */
	protected Timer _maintenanceTask;

	private static final int MONSTER_MAINTENANCE_INTERVAL = 3000;

	/**
	 * Constructor of L2MonsterInstance (use L2Character and L2NpcInstance constructor).<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Call the L2Character constructor to set the _template of the L2MonsterInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li> <li>Set the name of the L2MonsterInstance</li> <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it</li><BR>
	 * <BR>
	 * 
	 * @param objectId
	 *            Identifier of the object to initialized
	 * @param NpcTemplate
	 *            Template to apply to the NPC
	 */
	public FuzeMonsterInstance(long objectId, NpcTemplate template) {
		super(objectId, template);
		if (getTemplate().getMinionData() != null)
			_minionList = new MinionList(this);
		else
			_minionList = null;
	}

	@Override
	public final MonsterKnownList getKnownList() {
		return (MonsterKnownList) super.getKnownList();
	}

	@Override
	public void initKnownList() {
		setKnownList(new MonsterKnownList(this));
	}

	/**
	 * Return True if the attacker is not another L2MonsterInstance.<BR>
	 * <BR>
	 */
	@Override
	public boolean isAutoAttackable(L2Character attacker) {
		if (attacker instanceof L2Npc || !isAggressive())
			return false;

		return !isEventMob;
	}

	/**
	 * 返回true，如果L2MonsterInstance是有侵略性的(aggroRange > 0).<BR>
	 * <BR>
	 */
	@Override
	public boolean isAggressive() {
		return (getTemplate().aggroRange > 0) && !isEventMob;
	}

	@Override
	public void onSpawn() {
		super.onSpawn();
		deleteSpawnedMinions();
		startMaintenanceTask();
	}

	/**
	 * 开始维护出生仆从任务，延迟一定的时间出生所有的仆从
	 * 
	 */
	protected void startMaintenanceTask() {
		// maintenance task now used only for minions spawn
		if (_minionList == null)
			return;
		if (_maintenanceTask == null) {
			_maintenanceTask = new Timer(MONSTER_MAINTENANCE_INTERVAL, true, new Runnable() {
				public void run() {
					_minionList.spawnMinions();
				}
			});
		}
		if (!_maintenanceTask.isAlive())
			_maintenanceTask.start();
	}

	/**
	 * 呼叫管理的怪物仆从靠近自己
	 */
	public void callMinions() {
		if (hasMinions()) {
			for (L2MinionInstance minion : _minionList.getSpawnedMinions()) {
				if (minion == null || minion.isDead() || minion.isMovementDisabled())
					continue;

				// 检查仆从是否离主怪太远了
				if (!isInsideRadius(minion, 200) && !minion.isInCombat()) {
					// Calculate a new random coord for the minion based on the master's coord
					// but with minimum distance from master = 30
					minion.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(getX() + Rnd.get(-100, 100), getY() + Rnd.get(-100, 100)));
				}
			}
		}
	}

	/**
	 * 呼叫管理的仆从去帮助自己
	 * 
	 * @param attacker
	 *            攻击者
	 */
	public void callMinionsToAssist(L2Character attacker) {
		if (hasMinions()) {
			for (L2MinionInstance minion : _minionList.getSpawnedMinions()) {
				if (minion == null || minion.isDead())
					continue;

				// Trigger the aggro condition of the minion
				if (isRaid() && !isRaidMinion())
					minion.addDamageHate(attacker, 0, 100);
				else
					minion.addDamageHate(attacker, 0, 1);
			}
		}
	}

	@Override
	public boolean doDie(L2Character killer) {
		if (!super.doDie(killer))
			return false;

		if (_maintenanceTask != null) {
			if (_maintenanceTask.isAlive())
				_maintenanceTask.cancel();
		}

		if (hasMinions() && isRaid())
			deleteSpawnedMinions();
		return true;
	}

	public List<L2MinionInstance> getSpawnedMinions() {
		if (_minionList == null)
			return null;
		return _minionList.getSpawnedMinions();
	}

	public int getTotalSpawnedMinionsInstances() {
		if (_minionList == null)
			return 0;
		return _minionList.countSpawnedMinions();
	}

	public int getTotalSpawnedMinionsGroups() {
		if (_minionList == null)
			return 0;
		return _minionList.lazyCountSpawnedMinionsGroups();
	}

	/**
	 * 通知主怪仆从死亡
	 * 
	 * @param minion
	 */
	public void notifyMinionDied(L2MinionInstance minion) {
		_minionList.moveMinionToRespawnList(minion);
	}

	/**
	 * 通知主怪仆从重生
	 * 
	 * @param minion
	 */
	public void notifyMinionSpawned(L2MinionInstance minion) {
		_minionList.addSpawnedMinion(minion);
	}

	/**
	 * 是否有仆从
	 * 
	 * @return
	 */
	public boolean hasMinions() {
		if (_minionList == null)
			return false;
		return _minionList.hasMinions();
	}

	@Override
	public void deleteMe() {
		if (hasMinions()) {
			if (_maintenanceTask != null)
				_maintenanceTask.cancel();
			deleteSpawnedMinions();
		}
		super.deleteMe();
	}

	/**
	 * 死亡所有的已出生的仆从
	 */
	public void deleteSpawnedMinions() {
		if (_minionList == null)
			return;
		for (L2MinionInstance minion : getSpawnedMinions()) {
			minion.doDie(null);
			getSpawnedMinions().remove(minion);
		}
		_minionList.clearRespawnList();
	}
}
